package com.ndood.core.social;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.encrypt.Encryptors;
import org.springframework.social.config.annotation.EnableSocial;
import org.springframework.social.config.annotation.SocialConfigurerAdapter;
import org.springframework.social.connect.ConnectionFactoryLocator;
import org.springframework.social.connect.ConnectionSignUp;
import org.springframework.social.connect.UsersConnectionRepository;
import org.springframework.social.connect.jdbc.JdbcUsersConnectionRepository;
import org.springframework.social.connect.web.ProviderSignInUtils;

/**
 * 添加Social配置类
 * 社交登录拦截器：SocialAuthenticationFilter 登录的时候先经过这个拦截器，如果没code跳转到微信授权页，如果有code则跳转到qq链接进行登录后处理。
 * SocialAuthenticationFilter 
 * -> SocialAuthenticationService(Oauth2SocialAuthenticationService) 
 * -> ConnectionFactory 
 * -> Authentication(SocialAuthenticationToken) 
 * -> AuthenticationManager(ProviderManager)
 * -> AuthenticationProvider(SocialAuthenticationProvider)
 * -> UserConnectionRepository(JdbcUserConnectionRepository)
 * -> SocialUserDetailsService
 * -> SocialUserDetails
 */
@Configuration
@EnableSocial
public class SocialConfig extends SocialConfigurerAdapter{
	
	@Autowired
	private DataSource dataSource;
	
	/**
	 * UsersConnectionRepository包附近
	 * 建表 /org/springframework/social/connect/jdbc/JdbcUsersConnectionRepository.sql
	 */
	
	@Autowired(required = false)
	private ConnectionSignUp connectionSignUp;
	
	/**
	 * 获取用户Social持久化对象，并制定加密规则
	 */
	@Override
	public UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) {
		// TODO 修改加解密工具
		JdbcUsersConnectionRepository repository = new JdbcUsersConnectionRepository(dataSource, connectionFactoryLocator, Encryptors.noOpText());
		repository.setTablePrefix("auth_");
		
		// 使第一次社交登陆时，默默注册一个用户，而不跳转到注册页
		// imooc_userconnection会使用displayName作为Id插一条记录
		if(connectionSignUp!=null){
			repository.setConnectionSignUp(connectionSignUp);
		}
		return repository;
	}
	
	/**
	 * 声明社交登录注册工具类
	 */
	@Bean
	public ProviderSignInUtils providerSignInUtils(ConnectionFactoryLocator connectionFactoryLocator){
		return new ProviderSignInUtils(connectionFactoryLocator,getUsersConnectionRepository(connectionFactoryLocator));
	}

}